JAVA中线程同步的方法(7种)汇总

您所在的位置:网站首页 多线程访问同一个变量 同步机制的方法有几种 JAVA中线程同步的方法(7种)汇总

JAVA中线程同步的方法(7种)汇总

2024-07-15 14:01| 来源: 网络整理| 查看: 265

同步的方法:一、同步方法

  即有synchronized关键字修饰的方法。 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。

注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。

二、同步代码块

  即有synchronized关键字修饰的语句块。 被该关键字修饰的语句块会自动被加上内置锁,从而实现同步

代码如:

代码语言:javascript复制1synchronized(object){ 2}

注:同步是一种高开销的操作,因此应该尽量减少同步的内容。通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。

代码语言:javascript复制 1 package com.xhj.thread; 2 3 /** 4 * 线程同步的运用 5 * 6 * @author XIEHEJUN 7 * 8 */ 9 public class SynchronizedThread { 10 11 class Bank { 12 private int account = 100; 13 public int getAccount() { 14 return account; 15 } 16 17 /** 18 * 用同步方法实现 19 * 20 * @param money 21 */ 22 public synchronized void save(int money) { 23 account += money; 24 } 25 26 /** 27 * 用同步代码块实现 28 * 29 * @param money 30 */ 31 public void save1(int money) { 32 synchronized (this) { 33 account += money; 34 } 35 } 36 } 37 38 39 40 41 42 43 44 45class NewThread implements Runnable { 46 private Bank bank; 47 48 public NewThread(Bank bank) { 49 this.bank = bank; 50 } 51 52 @Override 53 public void run() { 54 for (int i = 0; i < 10; i++) { 55 // bank.save1(10); 56 bank.save(10); 57 System.out.println(i + "账户余额为:" + bank.getAccount()); 58 } 59 } 60 61 } 62 63 /** 64 * 建立线程,调用内部类 65 */ 66 public void useThread() { 67 Bank bank = new Bank(); 68 NewThread new_thread = new NewThread(bank); 69 System.out.println("线程1"); 70 Thread thread1 = new Thread(new_thread); 71 thread1.start(); 72 System.out.println("线程2"); 73 Thread thread2 = new Thread(new_thread); 74 thread2.start(); 75 } 76 77 public static void main(String[] args) { 78 SynchronizedThread st = new SynchronizedThread(); 79 st.useThread(); 80 } 81 82 }

=====================================

示例加讲解:

同步是多线程中的重要概念。同步的使用可以保证在多线程运行的环境中,程序不会产生设计之外的错误结果。同步的实现方式有两种,同步方法和同步块,这两种方式都要用到synchronized关键字。

同步方法:给一个方法增加synchronized修饰符之后就可以使它成为同步方法,这个方法可以是静态方法和非静态方法,但是不能是抽象类的抽象方法,也不能是接口中的接口方法。

下面代码是一个同步方法的示例:

代码语言:javascript复制1public synchronized void aMethod() { 2 // do something 3} 4 5public static synchronized void anotherMethod() { 6 // do something 7}

线程在执行同步方法时是具有排它性的。当任意一个线程进入到一个对象的任意一个同步方法时,这个对象的所有同步方法都被锁定了,在此期间,其他任何线程都不能访问这个对象的任意一个同步方法,直到这个线程执行完它所调用的同步方法并从中退出,从而导致它释放了该对象的同步锁之后。在一个对象被某个线程锁定之后,其他线程是可以访问这个对象的所有非同步方法的。

同步块:同步块是通过锁定一个指定的对象,来对同步块中包含的代码进行同步;而同步方法是对这个方法块里的代码进行同步,而这种情况下锁定的对象就是同步方法所属的主体对象自身。如果这个方法是静态同步方法呢?那么线程锁定的就不是这个类的对象了,也不是这个类自身,而是这个类对应的java.lang.Class类型的对象。同步方法和同步块之间的相互制约只限于同一个对象之间,所以静态同步方法只受它所属类的其它静态同步方法的制约,而跟这个类的实例(对象)没有关系。

如果一个对象既有同步方法,又有同步块,那么当其中任意一个同步方法或者同步块被某个线程执行时,这个对象就被锁定了,其他线程无法在此时访问这个对象的同步方法,也不能执行同步块。

synchronized 关键字用于保护共享数据。请大家注意“共享数据”,你一定要分清哪些数据是共享数据,请看下面的例子:

代码语言:javascript复制 1public class ThreadTest implements Runnable{ 2 3public synchronized void run(){ 4  for(int i=0;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3